package com.hillstone.component.util;

/**
 * @author dengliu
 */

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;

/**
 * @author wangjian2
 * @date 2022/3/15 15:11
 * @descripton
 */
public class AnnotationResolver {
    private Logger logger = LoggerFactory.getLogger(AnnotationResolver.class);
    private static AnnotationResolver resolver;

    public static AnnotationResolver newInstance() {
        if (resolver == null) {
            return new AnnotationResolver();
        } else {
            return resolver;
        }
    }

    /**
     * @author wangjian2
     * @date 2022/3/15 17:19
     * @description 解析字符串
     * @param joinPoint:
     * @param str:
     * @return: java.lang.Object
     **/
    public String resolver(JoinPoint joinPoint, String str, String keyPrefix) {
        if (str == null) {
            return null;
        }
        Object value = null;
        // 如果name匹配上了#{},则把内容当作变量
        if (str.matches("#\\{\\D*\\}")) {
            String newStr = str.replace("#{", "").replace("}", "");

            // 复杂类型
            if (newStr.contains(".")) {
                try {
                    value = complexResolver(joinPoint, newStr);
                } catch (Exception e) {
                    logger.error(e.getMessage(), e);
                }
            } else {
                value = simpleResolver(joinPoint, newStr);
            }
            return keyPrefix + value;
        } else { //非变量
            return str;
        }
    }

    /**
     * @author wangjian2
     * @date 2022/3/15 17:19
     * @description 解析复杂参数
     * @param joinPoint:
     * @param str:
     * @return: java.lang.Object
     **/
    private Object complexResolver(JoinPoint joinPoint, String str) {

        try {
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

            String[] names = methodSignature.getParameterNames();
            Object[] args = joinPoint.getArgs();
            String[] strArray = str.split("\\.");

            for (int i = 0; i < names.length; i++) {
                if (strArray[0].equals(names[i])) {
                    Object obj = args[i];
                    Method method = obj.getClass().getDeclaredMethod(getMethodName(strArray[1]), null);
                    Object value = method.invoke(args[i]);
                    return getValue(value, 1, strArray);
                }
            }

        } catch (Exception e) {
            logger.error("Error: annotation analysis error!");
        }
        return null;

    }

    /**
     * @author wangjian2
     * @date 2022/3/15 17:19
     * @description
     * @param obj:
     * @param index:
     * @param strArray:
     * @return: java.lang.Object
     **/
    private Object getValue(Object obj, int index, String[] strArray) {

        try {
            if (obj != null && index < strArray.length - 1) {
                Method method = obj.getClass().getDeclaredMethod(getMethodName(strArray[index + 1]), null);
                obj = method.invoke(obj);
                getValue(obj, index + 1, strArray);
            }

            return obj;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private String getMethodName(String name) {
        return "get" + name.replaceFirst(name.substring(0, 1), name.substring(0, 1).toUpperCase());
    }


    private Object simpleResolver(JoinPoint joinPoint, String str) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] names = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        for (int i = 0; i < names.length; i++) {
            if (str.equals(names[i])) {
                return args[i];
            }
        }
        return null;
    }
}
